/*
* MSSQL10.GeometryFactory - linestring geometry handler
* 
* initial implementation : 14.11.2008
*
* Copyright (c) Adam Sida, asida@centrum.cz.
* All rights reserved.
* 
* for license see Petra.Gis.License.txt
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Petra.Gis.Geometry;
using Petra.Gis.Geometry.Support;
using Petra.Gis.DataServices.MSSQL10.Support;

namespace Petra.Gis.DataServices.MSSQL10
{



  public partial class GeometryFactory
  {


    private static readonly byte[] _lineStringSuffix = new byte[] {
      0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 
      0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 
      0xFF, 0x00, 0x00, 0x00, 0x00, 0x02 };

    /***********************************************
     * 28.8.2007
     * 
     * creates linestringGeometry
     * from blob structure
     * 
     * asida@centrum.cz, initial implementation
     *************************************************/
    //private static GeometryBase binaryToLinestring(BinaryReader mBReader, System.Type parentGeomType)
    //{
    //  //skip SRID
    //  mBReader.BaseStream.Position += 4;

    //  //read coordlist type
    //  SqlSvrCoordListTypeEnum cListType = (SqlSvrCoordListTypeEnum)mBReader.ReadInt16();

    //  //advance stream position to first linestring coordinate (skip geometry type)
    //  mBReader.BaseStream.Position += 4;

    //  CoordinateList Coords = CoordinateListConverter.ToCoordinateList(mBReader/*, arrayOffset + 5*/, Dimension.dim2D, dataEndian);
    //  LineString oGeom = new LineString();
    //  oGeom.coordList = Coords;

    //  return oGeom;
    //}




    private static GeometryBase binaryToSmallLinestring(BinaryReader mBReader, System.Type parentGeomType)
    {
      //skip SRID
      mBReader.BaseStream.Position += 4;

      //read coordlist type
      //SqlSvrCoordListTypeEnum cListType = (SqlSvrCoordListTypeEnum)mBReader.ReadInt16();
      //skip coordlist type
      mBReader.BaseStream.Position += 2;

      CoordinateList Coords = new CoordinateList(((SqlSvrMemoryStream)mBReader.BaseStream).GetBuffer(), (int)mBReader.BaseStream.Position, 2, Dimension.dim2D);

      LineString oGeom = new LineString();
      oGeom.coordList = Coords;

      return oGeom;
    }




    /***********************************************
    * 28.8.2007
    * 
    * creates WKB blob structure 
    * from linestringGeometry
    * 
    * asida@centrum.cz, initial implementation
    *************************************************/
    private static byte[] lineStringToBinary(GeometryBase geometry)
    {



      int lBlobSize;

      LineString _linestring = (LineString)geometry;

      //small linestring (2 points line)
      if (_linestring.coordList.Count == 2)
        return smallLineStringToBinary(_linestring);

      //ok larger shape...
      lBlobSize = 4 + 2 + 4 + (_linestring.coordList.Count * 16) + 4 + 18;

      System.IO.MemoryStream oIMStream = new System.IO.MemoryStream(lBlobSize);
      System.IO.BinaryWriter mBWriter = new System.IO.BinaryWriter(oIMStream);

      oIMStream.Position = 0;

      mBWriter.Write((Int32)0x00000000); //SRID
      if (_linestring.coordList.Count < 13)
        mBWriter.Write((Int32)SqlSvrCoordListTypeEnum.ShortCoordList); //coordlist type
      else
        mBWriter.Write((Int32)SqlSvrCoordListTypeEnum.LongCoordList); //coordlist type

      mBWriter.Write((Int32)_linestring.coordList.Count);
      mBWriter.Write(_linestring.coordList.ToArray(Dimension.dim2D));
      mBWriter.Write((Int32)1); //num of strings = 1
      mBWriter.Write(_lineStringSuffix); //some M$ magic...

      return oIMStream.ToArray();
    }





    private static byte[] smallLineStringToBinary(LineString _linestring)
    {

      if (_linestring.coordList.Count > 2)
        throw new ArgumentOutOfRangeException("invalid call");

      int lBlobSize = 4 + 2 + 32; //(_linestring.coordList.Count * 16);

      System.IO.MemoryStream oIMStream = new System.IO.MemoryStream(lBlobSize);
      System.IO.BinaryWriter mBWriter = new System.IO.BinaryWriter(oIMStream);

      oIMStream.Position = 0;

      mBWriter.Write((Int32)0); //SRID
      mBWriter.Write((Int32)SqlSvrCoordListTypeEnum.Line); //coordlist type

      mBWriter.Write(_linestring.coordList.ToArray(Dimension.dim2D));

      return oIMStream.ToArray();
    }


  }

}
